﻿using Newtonsoft.Json.Linq;
using STHPMS1.BLL.B_Core;
using STHPMS1.Common.C_Entity.Stmpms1;
using STHPMS1.ICore;
using STHPMS1.ICore.I_BLL.Bus;
using STHPMS1.ICore.I_DAL;
using STHPMS1.ICore.I_Entity.Info;
using STHPMS1.ICore.I_Entity.Stmpms1;
using STHPMS1.ICore.I_Serv;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Linq;
using STHPMS1.Common.C_Enum;
using STHPMS1.Common.C_Extension;
using EmitMapper;
using STHPMS1.Common.C_Entity;

namespace STHPMS1.BLL.B_Bus
{
    public class B_RdstandardBus : BllBase, IB_RdstandardBill
    {
        public void Save<T>(T entity)
            where T : class ,IB_Rdstandard
        {
            this.Scene.Dal.Sthpms1.Save(entity);
        }

        public void Remove(string rdwayid)
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            using (IDbTransaction dbTrans = dao.BeginTransaction())
            {
                List<B_Rdstandard> standardList = dao.Select<B_Rdstandard>(p => p.Rdwayid == rdwayid);
                List<B_Rdstandard_History> historyList = new List<B_Rdstandard_History>();
                foreach (var item in standardList)
                {
                    B_Rdstandard_History history=ObjectMapperManager.DefaultInstance.GetMapper<B_Rdstandard, B_Rdstandard_History>().Map(item);
                    history.Importdate = DateTime.Now;
                    historyList.Add(history);
                }

                if (historyList.Count>0)dao.SaveAll(historyList);
                dao.Delete<B_Rdstandard>(p => p.Rdwayid == rdwayid);
                dbTrans.Commit();
            }
        }


        public IEnumerable<T> Get<T>(Expression<Func<T, bool>> predicate, IPagingInfo info)
            where T : class, IB_Rdstandard
        {

            return this.Scene.Dal.Sthpms1.Select<T>(predicate, info,k=>k.Importdate,true);
        }

        public DataTable GetRdStandard(IPagingInfo info)
        {
            DataTable dt=this.Scene.Dal.Sthpms1.B_Rdstandard.GetRdStandard();
            int currentPageIndex=info.PageIndex;
            int pageSize=info.PageSize;

            DataTable newdt = dt.Clone();

            int rowbegin = currentPageIndex * pageSize;//当前页的第一条数据在dt中的位置
            int rowend = (currentPageIndex+1) * pageSize;//当前页的最后一条数据在dt中的位置
 
            if (rowbegin >= dt.Rows.Count)
            {
                return newdt;
            }
 
            if (rowend > dt.Rows.Count)
            {
                rowend = dt.Rows.Count;
            }
 
            DataView dv = dt.DefaultView;
            for (int i = rowbegin; i <= rowend - 1; i++)
            {
                newdt.ImportRow(dv[i].Row);
            }

            info.TotalRecords = dt.Rows.Count;
 
            return newdt;
        }

        public void SaveRdStandard(string rdwayid, string data)
        {
            if (string.IsNullOrEmpty(rdwayid)) throw new Exception("请选择路线!");

            List<B_Rdstandard> rdList = new List<B_Rdstandard>();
            double version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdwayid);

            foreach (JProperty item in JObject.Parse(data).Properties())
            {
                int key = int.Parse(item.Name.Replace("R", ""));
                JObject d=item.Value as JObject;
                JArray objs = d.Property("data").Value as JArray;

                for (int i = 0; i < objs.Count-1; i++)
                {
                    JObject child = objs[i] as JObject;
                    B_Rdstandard standard = new B_Rdstandard();
                    standard.Rdwayid = rdwayid;
                    standard.Changetype_Dictid = key;
                    standard.Importdate = DateTime.Now;
                    standard.His_Version = version;

                    if (!string.IsNullOrEmpty(child["Beginmp"].Value<string>()))
                        standard.Beginmp = child["Beginmp"].Value<double>();
                    else
                        throw new Exception(item.Name+"桩号不能为空!");

                    if (!string.IsNullOrEmpty(child["Value"].Value<string>()))
                        standard.Value = child["Value"].Value<string>();
                    else
                    {
                        if (standard.Changetype_Dictid != RdStandardTypeEnum.R207.GetEnumValue())
                            throw new Exception(item.Name + "值不能为空!");
                    }


                    standard.Stand_Id = MyApp.Locator.GetInstance<IKeyGenrateService>().NewRdStandard(
                        standard.Rdwayid,
                        standard.Direction_Dictid??0,
                        standard.Changetype_Dictid??0,
                        standard.Beginmp??0);

                    rdList.Add(standard);
                }
            }

            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            using (IDbTransaction dbTrans = dao.BeginTransaction())
            {
                dao.Delete<B_Rdstandard>(p => p.Rdwayid == rdwayid);
                if (rdList.Count>0)dao.SaveAll<B_Rdstandard>(rdList);
                dbTrans.Commit();
            }
        }

        public dynamic GetRdStandardDeatil(string rdwayid)
        {
            if (string.IsNullOrEmpty(rdwayid)) throw new Exception("请选择路线!");

            B_Roadway road = this.Scene.Dal.Sthpms1.Single<B_Roadway>(p => p.Rdwayid==rdwayid);
            if (road == null) throw new Exception("路线数据不存在-"+rdwayid);
            List<B_Rdstandard> standList= this.Scene.Dal.Sthpms1.Select<B_Rdstandard>(p=>p.Rdwayid==rdwayid ,new DefPageInfo(),k=>k.Beginmp);

            JObject standards = new JObject();
            AddStake(road, standList, RdStandardTypeEnum.R202, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R203, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R204, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R205, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R206, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R207, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R208, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R209, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R210, ref standards);
            AddStake(road, standList, RdStandardTypeEnum.R211, ref standards);          
            
            return standards;
        }

        private void AddStake(B_Roadway road, List<B_Rdstandard> standList, RdStandardTypeEnum type, ref JObject standards)
        { 
            string name=type.GetEnumName();
            JArray data = new JArray();

            foreach (B_Rdstandard standard in standList.Where(p => p.Changetype_Dictid == type.GetEnumValue()))
            {
                JObject item = new JObject();
                item["Beginmp"] = standard.Beginmp;
                item["Value"] = standard.Value;
                data.Add(item);
            }

            if (data.Count == 0)
            { 
                JObject itemBegin = new JObject();
                itemBegin["Beginmp"] = road.Beginmp;
                itemBegin["Value"] = "";
                data.Add(itemBegin);
            }

            JObject itemEnd= new JObject();
            itemEnd["Beginmp"] = road.Endmp;
            itemEnd["Value"] = "";
            data.Add(itemEnd);

            JObject obj=new JObject();
            obj.Add("data",data);
            standards.Add(name,obj);
        }

        public void CheckMp(string rdid, double begin,double end)
        {
            this.Scene.Dal.Sthpms1.B_Rdstandard.CheckMp(rdid, begin,end);
        }
    }
}
